package com.centerserver;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

public class CenterServer extends JFrame {

	private static final long serialVersionUID = 1L;

	private JList mCaptureEndList;
	private JList mCaptureVideoItemList;
	private DefaultListModel mCaptureEndListModel;
	private DefaultListModel mCaptureVideoItemListModel;
	private JTable mReceivedMsgTable;
	private DefaultTableModel mReceivedMsgTableModel;
	private final static String mStartString = "Start Server";
	private final static String mStopString = "Stop Server";
	private JButton mStartStopButton;
	private JLabel mCaptureEndInfo;

	private boolean mIsServerStarted;
	private CaptureEndServerThread mCaptureEndServerThread;
	private DatabaseManager mDatabaseManager;

//	// record the multicast address corresponding to one capture end
//	private Map<String, InetAddress> mInetAddrMap;
	
	// record the monitor end list 
	private Map<String, List<String>> mMonitorListMap;

	public CenterServer() {

		super("CenterServer");
		
		mIsServerStarted = false;
		
		mStartStopButton = new JButton(mStartString);
		mStartStopButton.addActionListener(new StartStopListener());

		JPanel buttonPane = new JPanel();
		buttonPane.setAlignmentX(CENTER_ALIGNMENT);
		buttonPane.setAlignmentY(CENTER_ALIGNMENT);
		buttonPane.add(mStartStopButton);

		mCaptureEndListModel = new DefaultListModel();
		mCaptureEndList = new JList(mCaptureEndListModel);
		mCaptureEndList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		mCaptureEndList.setVisibleRowCount(5);
		mCaptureEndList
				.addListSelectionListener(new CaptureEndSelectionListener());
		mCaptureEndList.addFocusListener(new CaptureEndFocusListener());
		mCaptureEndList.setFixedCellWidth(240);
		JScrollPane listScrollPane1 = new JScrollPane(mCaptureEndList);

		mCaptureVideoItemListModel = new DefaultListModel();
		mCaptureVideoItemList = new JList(mCaptureVideoItemListModel);
		mCaptureVideoItemList
				.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		mCaptureVideoItemList
				.addListSelectionListener(new CaptureVideoItemSelectionListener());
		mCaptureVideoItemList.addFocusListener(new CapVideoItemFocusListener());
		mCaptureVideoItemList.setVisibleRowCount(5);
		mCaptureVideoItemList.addMouseListener(new CaptureVideoMouseListener());
		mCaptureVideoItemList.setFixedCellWidth(240);
		JScrollPane listScrollPane2 = new JScrollPane(mCaptureVideoItemList);
		
		mReceivedMsgTableModel  = new DefaultTableModel();
		mReceivedMsgTableModel.addColumn("Time");
		mReceivedMsgTableModel.addColumn("Sender");
		mReceivedMsgTableModel.addColumn("Receiver");
		mReceivedMsgTableModel.addColumn("Command type");
		mReceivedMsgTableModel.addColumn("Argument1");
		mReceivedMsgTableModel.addColumn("Argument2");
		mReceivedMsgTableModel.addColumn("Argument3");
		mReceivedMsgTable = new JTable(mReceivedMsgTableModel);
		JScrollPane listScrollPane3 = new JScrollPane(mReceivedMsgTable);
		

		JPanel pan = new JPanel();
		BoxLayout bl = new BoxLayout(pan, BoxLayout.X_AXIS);
		pan.setLayout(bl);
		pan.add(listScrollPane1);
		pan.add(listScrollPane2);
		
		JPanel pan2 = new JPanel();
		BoxLayout bl2 = new BoxLayout(pan2, BoxLayout.Y_AXIS);
		pan2.setLayout(bl2);
		pan2.add(pan);
		pan2.add(listScrollPane3);
		
		mCaptureEndInfo = new JLabel();
		mCaptureEndInfo.setText(" ");

		add(buttonPane, BorderLayout.NORTH);
		add(pan2, BorderLayout.CENTER);
		add(mCaptureEndInfo, BorderLayout.SOUTH);
		setBounds(0, 0, 500, 500);
		
		setVisible(true);
		//setResizable(false);
		
		addWindowListener(new CenterServerWindowListener());

	}

	class CaptureEndSelectionListener implements ListSelectionListener {

		@Override
		public void valueChanged(ListSelectionEvent e) {
			
			// clear the capture video item list
			mCaptureVideoItemListModel.removeAllElements();

			String captureEndName = (String) mCaptureEndList.getSelectedValue();
			List<String> videoNameList = mDatabaseManager
					.getAllCaptureVideo(captureEndName);
			boolean isAvailable = mDatabaseManager
					.isCaptureEndAvailable(captureEndName);
			mCaptureEndInfo.setText(isAvailable ? "connected" : "unconnected");

			for (int i = 0; i < videoNameList.size(); i++) {
				mCaptureVideoItemListModel.addElement(videoNameList.get(i));
			}
		}

	}

	class CaptureEndFocusListener implements FocusListener {

		@Override
		public void focusGained(FocusEvent e) {
			String captureEndName = (String) mCaptureEndList.getSelectedValue();

			if (captureEndName == null || captureEndName.length() < 1)
				return;

			boolean isAvailable = mDatabaseManager
					.isCaptureEndAvailable(captureEndName);
			mCaptureEndInfo.setText(isAvailable ? "connected" : "unconnected");
		}

		@Override
		public void focusLost(FocusEvent e) {

		}

	}

	class CaptureVideoItemSelectionListener implements ListSelectionListener {

		@Override
		public void valueChanged(ListSelectionEvent e) {

			String tip = "Double Click to View---";
			String videoName = (String) mCaptureVideoItemList
					.getSelectedValue();
			
			if(videoName == null || videoName.length()<1 )
				return;

			String videoItemInfo = "Captured from ";
			videoItemInfo += videoName.substring(8);
			videoItemInfo += ":00 to ";
			videoItemInfo += Integer.parseInt(videoName.substring(8)) + 1;
			videoItemInfo += ":00 at ";
			videoItemInfo += videoName.substring(0, 4);
			videoItemInfo += "-";
			videoItemInfo += videoName.substring(4, 6);
			videoItemInfo += "-";
			videoItemInfo += videoName.substring(6, 8);

			mCaptureEndInfo.setText(tip.concat(videoItemInfo));
		}

	}

	class CapVideoItemFocusListener implements FocusListener {

		@Override
		public void focusGained(FocusEvent e) {
			String tip = "Double Click to View---";
			String videoName = (String) mCaptureVideoItemList
					.getSelectedValue();

			if (videoName == null || videoName.length() < 1) {
				return;
			}

			String videoItemInfo = "Captured from ";
			videoItemInfo += videoName.substring(8);
			videoItemInfo += ":00 to ";
			videoItemInfo += Integer.parseInt(videoName.substring(8)) + 1;
			videoItemInfo += ":00 at ";
			videoItemInfo += videoName.substring(0, 4);
			videoItemInfo += "-";
			videoItemInfo += videoName.substring(4, 6);
			videoItemInfo += "-";
			videoItemInfo += videoName.substring(6, 8);

			mCaptureEndInfo.setText(tip.concat(videoItemInfo));
		}

		@Override
		public void focusLost(FocusEvent e) {

		}

	}

	class StartStopListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {

			if (mIsServerStarted)
				doStop();
			else
				doStart();

			mStartStopButton.setText(mIsServerStarted ? mStartString
					: mStopString);
			mIsServerStarted = !mIsServerStarted;
		}

		private void doStop() {
			
			// terminate the capture end server thread
			mCaptureEndServerThread.setFinished();
			
			mDatabaseManager.disableAllCaptureEnd();
			
			mCaptureEndList.requestFocus();
		}

		private void doStart() {

			/**
			 * establish the database connection
			 */
			mDatabaseManager = new DatabaseManager();
			if (mDatabaseManager.connectDatabase()) {
				System.out.println("Connect Database Successfully!");
			} else {
				System.out.println("Connect Database Failed!!!");
				return;
			}

			/**
			 * get all capture end
			 */
			// clear the capture end list
			mCaptureEndListModel.removeAllElements();
			List<String> captureEndList = mDatabaseManager
					.getAllCaptureEndName();
			for (int i = 0; i < captureEndList.size(); i++) {
				mCaptureEndListModel.addElement(captureEndList.get(i));
			}
			mCaptureEndList.setSelectedIndex(0);
			
//			mInetAddrMap = new HashMap<String, InetAddress>();
			mMonitorListMap = new HashMap<String, List<String>>();

			/**
			 * start the two socket, mCaptureEndServerSocket &
			 * mMonitorEndServerSocket
			 */
			mCaptureEndServerThread = new CaptureEndServerThread(
					mCaptureEndListModel, 
					mCaptureVideoItemListModel,
					mDatabaseManager,
					mMonitorListMap/*,
					mInetAddrMap*/);
			mCaptureEndServerThread.start();

			MonitorEndServerThread monitorEndServerThread = new MonitorEndServerThread(
					mDatabaseManager,
					mMonitorListMap/*, 
					mInetAddrMap*/);
			monitorEndServerThread.start();
			
			/**
			 * listen the command of monitor end
			 */
			ListenMonitorCommandThread listenMonitorCommandThread = new ListenMonitorCommandThread(mReceivedMsgTableModel);
			listenMonitorCommandThread.start();
		}
	}
	
	class CenterServerWindowListener implements WindowListener {

		@Override
		public void windowActivated(WindowEvent e) {
			
		}

		@Override
		public void windowClosed(WindowEvent e) {
			
		}

		@Override
		public void windowClosing(WindowEvent e) {
			
			if( null != mCaptureEndServerThread)
				mCaptureEndServerThread.setFinished();
			if( null != mDatabaseManager)
				mDatabaseManager.disableAllCaptureEnd();
			
			System.exit(0);
		}

		@Override
		public void windowDeactivated(WindowEvent e) {
			
		}

		@Override
		public void windowDeiconified(WindowEvent e) {
			
		}

		@Override
		public void windowIconified(WindowEvent e) {
			
		}

		@Override
		public void windowOpened(WindowEvent e) {
			
		}
		
	}
	
	class CaptureVideoMouseListener implements MouseListener {

		@Override
		public void mouseClicked(MouseEvent e) {
			
			// double clicked
			if( 2 == e.getClickCount() ) {
				System.out.println("double click item");
				
				String fileName = CenterServerConfig.RECORD_VIDEO_FULL_PATH_ROOT_DIR;
				
				String selectedValue = (String) mCaptureEndList.getSelectedValue();
				if( null == selectedValue )
					return;
				
				fileName = fileName.concat(selectedValue);
				fileName = fileName.concat("\\");
				
				selectedValue = (String) mCaptureVideoItemList.getSelectedValue();
				if( null == selectedValue )
					return;
				
				fileName = fileName.concat(selectedValue);
				fileName = fileName.concat(".264");
				
				System.out.println(fileName);
				
				new H264Player(fileName, 320, 240);
			}
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			
		}

		@Override
		public void mouseExited(MouseEvent e) {
			
		}

		@Override
		public void mousePressed(MouseEvent e) {
			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			
		}
		
	}

	/**
	 *
	 */
	public static void main(String[] args) {

		new CenterServer();
	}

}
